# Лекция: Абстракция и абстрактные классы в Java

Абстракция - это один из основных принципов объектно-ориентированного программирования. Он позволяет скрыть детали реализации и предоставить только необходимый функционал.

Абстрактные классы и методы в Java используются для создания классов и методов, которые не могут быть инстанциированы (не могут быть использованы для создания объектов; проще говоря, нельзя создать объект через new SomeClassName()), и должны быть наследованы и реализованы в подклассах.

## Абстрактные классы

Абстрактный класс объявляется с помощью ключевого слова `abstract`.

```java
abstract class AbstractClass {
    // код класса
}
```

## Абстрактные методы

Абстрактный метод объявляется с помощью ключевого слова `abstract` и не имеет тела.

```java
abstract void abstractMethod();
```

---

# Практические задания

1. **Создайте абстрактный класс `Animal` с абстрактным методом `makeSound`.** (Сложность: 1/5)
```java
abstract class Animal {
    abstract void makeSound();
}
```

2. **Создайте класс `Dog`, который наследуется от абстрактного класса `Animal` и реализует метод `makeSound`.** (Сложность: 2/5)
```java
class Dog extends Animal {
    @Override
    void makeSound() {
        System.out.println("Woof!");
    }
}
```

3. **Создайте класс `Cat`, который наследуется от абстрактного класса `Animal` и реализует метод `makeSound`.** (Сложность: 2/5)
```java
class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("Meow!");
    }
}
```

4. **Создайте абстрактный класс `Shape` с абстрактным методом `getArea`. Создайте класс `Rectangle`, который наследуется от `Shape` и реализует метод `getArea`, и класс `Circle`, который также наследуется от `Shape` и реализует метод `getArea`.** (Сложность: 3/5)
```java
abstract class Shape {
    abstract double getArea();
}

class Rectangle extends Shape {
    double width;
    double height;

    @Override
    double getArea() {
        return width * height;
    }
}

class Circle extends Shape {
    double radius;

    @Override
    double getArea() {
        return Math.PI * radius * radius;
    }
}
```

5. **Создайте абстрактный класс `Vehicle` с абстрактными методами `drive` и `stop`. Создайте класс `Car`, который наследуется от `Vehicle` и реализует методы `drive` и `stop`, и класс `Bicycle`, который также наследуется от `Vehicle` и реализует методы `drive` и `stop`.** (Сложность: 4/5)
```java
abstract class Vehicle {
    abstract void drive();
    abstract void stop();
}

class Car extends Vehicle {
    @Override
    void drive() {
        System.out.println("Driving a car...");
    }

    @Override
    void stop() {
        System.out.println("Stopping a car...");
    }
}

class Bicycle extends Vehicle {
    @Override
    void drive() {
        System.out.println("Riding a bicycle...");
    }

    @Override
    void stop() {
        System.out.println("Stopping a bicycle...");
    }
}
```